package Main;

import Business.FinalAll;
import Business.Room;
import Message.Storage;
import Message.Tips;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.io.*;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 启动类
 */
public class StartMain implements ServletContextListener {

    private static Map<String , Map<String , Object>> configData = new HashMap<>();//配置内容存储类
    private static Yaml yml;//yml类型
    public static List<String> ArticleTypes = null;

    /**
     * 启动时
     */
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        Date startDate = new Date();//起始时间
        Tips.Info("后端正在启动......");
        if (runStart()){//启动服务器
            //启动成功
            Date endDate = new Date();//结束时间
            long spanTime = endDate.getTime() - startDate.getTime();
            Tips.Info("后端已启动，耗时：" + spanTime + " 毫秒");
        }else{
            //启动失败
            Date endDate = new Date();//结束时间
            long spanTime = endDate.getTime() - startDate.getTime();
            Tips.Info("后端启动失败，耗时：" + spanTime + " 毫秒");
        }
    }

    /**
     * 服务器启动函数
     */
    private boolean runStart(){
        DumperOptions dumperOptions = new DumperOptions();
        dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
        dumperOptions.setDefaultScalarStyle(DumperOptions.ScalarStyle.SINGLE_QUOTED);
        dumperOptions.setPrettyFlow(false);
        yml = new Yaml(dumperOptions);//初始化yml
        if (checkFile()){
            //成功
            Tips.Info("检查配置文件正常!");
        }else{
            Tips.Error("检查配置文件异常!");
            return false;
        }
        if (FinalAll.init()){
            Tips.Info("变量初始化正常!");
        }else {
            Tips.Error("变量初始化异常!");
            return false;
        }
        if (Mysql.Start.Mysql_Start()) {//启动mysql
            Tips.Info("MYSQl连接正常!");
        }else {
            Tips.Error("MYSQl连接异常!");
            return false;
        }
        if (Room.init()){//房间初始化
            Tips.Info("房间初始化正常!");
        }else {
            Tips.Error("房间初始化异常!");
            return false;
        }
        if (Storage.ClockStart()){//启动日志时钟
            Tips.Info("日志时钟启动正常!");
        }else{
            Tips.Info("日志时钟启动异常!");
            return false;
        }
        text.run();//调用测试方法
        return true;
    }


    /**
     * 检查文件是否正常
     */
    public boolean checkFile(){
        if (!checkFile_Files(FinalAll.projectName)) return false;//检查目录
        if (!checkFile_Files(FinalAll.projectName + "/log")) return false;//检查目录
        if (!checkFile_File(FinalAll.projectName + "/" , "mysql")) return false;//检查文件
        if (!checkFile_File(FinalAll.projectName + "/" , "config")) return false;//检查文件
        return true;
    }

    /**
     * 检查目录
     */
    private boolean checkFile_Files(String file){
        File file1 = new File(file);
        Tips.Info("配置目录：" + file1.getAbsolutePath());
        if (!file1.exists()){//文件不存在
            file1.mkdirs();//创建文件目录
        }
        return true;
    }

    /**
     * 检查文件
     */
    private boolean checkFile_File(String file , String name){
        File file1 = new File(file + name + ".yml");
        Tips.Info("配置目录：" + file1.getAbsolutePath());
        if (!file1.exists()) copyFile(file , name);//文件不存在时
        StringBuilder stringBuilder = readFile(file1);//读取文件内容
        Map<String, Object> locData = null;
        for (int i = 1; i >= 0 ; i--){
            try {
                locData = yml.load(stringBuilder.toString());
                break;
            }catch (Exception e){
                Tips.Warm(e.toString());//打印异常
            }
            file1.delete();//删除文件
            copyFile(file , name);//复制文件
            stringBuilder = readFile(file1);//读取文件内容
        }
        //完成读取配置文件
        if (locData == null){
            return false;
        }
        configData.put(name , locData);//写入配置内存中
        return true;
    }

    /**
     * 读取文件内容
     * @return stringBuilder
     */
    private StringBuilder readFile(File file){
        FileReader fileReader = null;
        BufferedReader bufferedReader = null;
        StringBuilder stringBuilder = new StringBuilder();
        try {
            fileReader = new FileReader(file);
            bufferedReader = new BufferedReader(fileReader);
            int len = -1;
            char[] buf = new char[1024];
            while (true){
                try {
                    if ((len = bufferedReader.read(buf)) == -1) break;
                } catch (IOException e) {
                    e.printStackTrace();
                }
                stringBuilder.append(buf, 0 , len);
            }
            //读取文件 stringBuffer
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return null;
        }finally {//关闭流
            if (bufferedReader != null){
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fileReader != null){
                try {
                    fileReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return stringBuilder;
    }

    /**
     * 写入配置文件到本地
     */
    private boolean copyFile(String file , String name){
        File file1 = new File(file + name + ".yml");
        FileWriter fileWriter = null;
        try {
            fileWriter = new FileWriter(file1 , false);
            yml.dump(YamlConfig.getConfig(name) , fileWriter);
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }finally {
            if (fileWriter != null){//关闭流
                try {
                    fileWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return true;
    }

    public static Yaml getYml() {
        return yml;
    }

    /**
     * 关闭时
     */
    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        Tips.Info("后端正在关闭！");
        Mysql.Start.disConnection();//断开数据库连接
        Tips.Info("后端已经关闭！" , false);
        Storage.stop();//停止日志运行
        Tips.Info("后端已经关闭！日志保存位置:" + FinalAll.projectName + "/log/");
    }

    /**
     * 获取配置文件信息
     * @param type 配置节
     * @return
     */
    public static Map<String, Object> getConfigData(String type) {
        return configData.get(type.toLowerCase());
    }



}
